//
//  TableVC.m
//  
//  jhf
//
//  Created by Mac on 2019/12/6.
//  Copyright © 2019 Mac. All rights reserved.
//

#import "TableVC.h"
#import "VCLifecycleProtocol.h"
#import "ActionableProtocol.h"
#import "TableConfigProtocol.h"
#import "TableVCVM.h"
#import "TableVC+NavBar.h"
#import "TableVC+Config.h"

@interface TableVC ()<ActionableProtocol, UIGestureRecognizerDelegate>

@property (nonatomic, strong, readwrite) Class vmClass;

@property (nonatomic, strong, readwrite) id model;

@property (nonatomic, strong) NSDate *tableLastRefreshTime;

@end

@implementation TableVC

//MARK: - 默认方法

// 配置keys和values
- (void)configKeys:(NSArray <NSString *> *)keys values:(NSArray *)values; {
    _keys = keys;
    _values = values;
    [self keysValuesSetter];
}

// 设置keys values
- (void)keysValuesSetter {
    // 我的key
    if (self.keys && [self.keys isKindOfClass:[NSArray class]]) {
        if (self.keys.count > 0 && self.values && self.keys.count == self.values.count) {
            NSArray *properties = self.vm.j_getAllProperties;
            [self.keys enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                if ([properties containsObject:obj]) {
                    [self.vm setValue:[self.values objectAtIndex:idx] forKey:obj];
                }else {
                    NSLog(@"❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️%@属性不存在", obj);
                }
            }];
        }else {
            NSLog(@"❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️keys 或者 values 传参不正确");
        }
        [self.vm configDown];
    }
}

// 判断vm
- (BOOL)isVM:(TableVCVM *)vm; {
    if (self.vm && vm && [vm isEqual:self.vm]) {
        return true;
    }
    return false;
}

- (BOOL)isVmClass:(NSString *)vmStr; {
    if (self.vm && [self.vm isKindOfClass:NSClassFromString(vmStr)]) {
        return true;
    }
    return false;
}

// cell 上面点击事件
- (void)actionTo:(id)model; {
    [self.vm actionTo:model];
}

// MARK: - 页面
- (void)drawView {
//    去掉 优化...
//    [self keysValuesSetter];
    self.throttleTime = 0.3;
    [self bindModel];
    [self configTableview];
}

// MARK:- 绑定
- (void)bindModel {
    // 绑定信号
    @weakify(self)
    [self.vm.signal subscribeNext:^(id  _Nullable x) {
        @strongify(self)
        if ([TABLE_DEFAULT_RELOAD_SIGNAL isEqualToString:x]) {
            [self.delayReloadSubject sendNext:@(++self.reloadCount)];
        }
        if ([TABLE_REFRESH_CONFIG_SIGNAL isEqualToString:x]) {
            [self refreshTableConfig];
        }
    }];
    
    // 检查footer
    [self.vm.checkFooterSignal subscribeNext:^(id  _Nullable x) {
        @strongify(self)
        if (self.enablePush) {
            [self.vm checkFooter:self.tableview result:x pagesize:self.pagesize];
        }
    }];
    
    // 滚动到第几个 indexpath
    [self.vm.scrollToSignal subscribeNext:^(id  _Nullable x) {
        @strongify(self)
        if ([x isKindOfClass:NSIndexPath.class]) {
            [self.tableview scrollToRowAtIndexPath:x atScrollPosition:UITableViewScrollPositionNone animated:true];
        }
    }];
    
    // 绑定信号 rows
//    [[[self.vm.rows changeSignal] throttle:0.2] subscribeNext:^(id  _Nullable x) {
//        @strongify(self)
//        [self.delayReloadSubject sendNext:@(++self.reloadCount)];
////        [self.tableview reloadData];
//    }];
    
    [[self.vm.rows changeSignal] subscribeNext:^(id  _Nullable x) {
        @strongify(self)
        [self.delayReloadSubject sendNext:@(++self.reloadCount)];
    }];
    
    // 绑定信号 sections
//    [[[self.vm.sections changeSignal] throttle:0.2] subscribeNext:^(id  _Nullable x) {
//        @strongify(self)
////        [self.tableview reloadData];
//        [self.delayReloadSubject sendNext:@(++self.reloadCount)];
//    }];
    [[self.vm.sections changeSignal] subscribeNext:^(id  _Nullable x) {
        @strongify(self)
        [self.delayReloadSubject sendNext:@(++self.reloadCount)];
    }];
    
    [[[[self.delayReloadSubject distinctUntilChanged] filter:^BOOL(id  _Nullable value) {
        @strongify(self)
        NSDate *refreshTiem = [NSDate new];
        self.tableLastRefreshTime = refreshTiem;
        self.isRefreshIng = true;
        return true;
    }] throttle:self.throttleTime] subscribeNext:^(id  _Nullable x) {
        @strongify(self)
        [self reloadTable:[NSDate new]];
        self.isRefreshIng = false;
    }];
    
//    [[self.delayReloadSubject distinctUntilChanged] subscribeNext:^(id  _Nullable x) {
//        @strongify(self)
//        NSDate *refreshTiem = [NSDate new];
//        self.tableLastRefreshTime = refreshTiem;
//        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//            @strongify(self)
//            [self reloadTable:refreshTiem];
//        });
//    }];
    
//    [[[self.delayReloadSubject distinctUntilChanged] throttle:0.2] subscribeNext:^(id  _Nullable x) {
//        @strongify(self)
//        MAIN(^{
//           [UIView performWithoutAnimation:^{
//               [self.tableview reloadData];
//           }];
//       });
//    }];
    
    // 绑定长按
    if (self.enableLongPress) {
        [self.vm configLongPress:self.tableview completion:^(NSIndexPath * _Nullable indexPath, UIGestureRecognizerState state) { }];
    }
}

// 节流刷新tableview
- (void)reloadTable:(NSDate *) methodTime {
    if (self.tableLastRefreshTime) {
        NSLog(@"------------>reload table-------------> %f", [methodTime timeIntervalSinceDate:self.tableLastRefreshTime]);
        if ([methodTime timeIntervalSinceDate:self.tableLastRefreshTime] > 0) {
            MAIN(^{
               [UIView performWithoutAnimation:^{
                   [self.tableview reloadData];
               }];
           });
        }
    }
}

// MARK:- 配置tableview
- (void)configTableview {
    @weakify(self);
    [self.view addSubview:self.tableview];
    [self.tableview mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.view).insets(UIEdgeInsetsZero);
    }];
    
    // 下拉
    if (self.enablePull) {
        [self.vm configHeader:self.tableview completion:nil];
    }
    
    // 空白点击手机键盘
    if (self.enableTapEmpty) {
        UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hiddeKeyboard:)];
        gestureRecognizer.delegate = self;
        gestureRecognizer.numberOfTapsRequired = 1;
        [self.tableview addGestureRecognizer:gestureRecognizer];
    }

    // tableview 代理绑定
    _tableview.estimatedRowHeight = 44.f;
    _tableview
    .configRun
    .sectionsCount(^NSInteger{
        @strongify(self)
        return [self.vm sectionsCount];
    })
    .rowsAction(^NSArray<UITableViewRowAction *> * _Nullable(NSIndexPath * _Nonnull indexPath, UITableView * _Nonnull tableView) {
        @strongify(self)
        return [self.vm rowActionIndexPath:indexPath tableView:tableView];
    })
    .emptyDataConfig(^CPEmptyDataConfig * _Nullable{
        @strongify(self)
        return self.enableEmptyConifg ? (self.emptyConifg ? self.emptyConifg : [CPEmptyDataConfig initWithTitle:@"暂无数据" imageName:TABLE_DEFAULT_NULL_IMAGE_NAME]) : nil;
    })
    .didScroll(^(UIScrollView * _Nonnull scrollView) {
        @strongify(self)
        if (self.scrollTo) {
            NSIndexPath *indexPath = [self.tableview indexPathForRowAtPoint:scrollView.contentOffset];
            [self.vm scrollTo:scrollView indexPath:indexPath];
        }
        if (self.enableTapEmpty) {
            [self cancelKeyboard];
        }
    })
    .sectionHeaderView(^UIView * _Nullable(NSInteger section, UITableView * _Nonnull tableView) {
        @strongify(self)
        return [self.vm sectionHeaderView:section tableView:tableView];
    })
    .sectionHeaderHeight(^CGFloat(NSInteger section, UITableView * _Nonnull tableView) {
        @strongify(self)
        return [self.vm sectionHeaderHeight:section tableView:tableView];
    })
    .sectionFooterView(^UIView * _Nullable(NSInteger section, UITableView * _Nonnull tableView) {
        @strongify(self)
        return [self.vm sectionFooterView:section tableView:tableView];
    })
    .sectionFooterHeight(^CGFloat(NSInteger section, UITableView * _Nonnull tableView) {
        @strongify(self)
        return [self.vm sectionFooterHeight:section tableView:tableView];
    })
    .selectSectionIndexTitles(^NSInteger(UITableView * _Nonnull tableView, NSString * _Nonnull title, NSInteger index) {
        @strongify(self)
        return [self.vm selectSectionIndexTitles:tableView title:title index:index];
    })
    .sectionIndexTitles(^NSArray<NSString *> * _Nullable(UITableView * _Nonnull tableView) {
        @strongify(self)
        return [self.vm sectionIndexTitles:tableView];
    })
    .cellCount(^NSInteger(NSInteger section, UITableView * _Nonnull tableView) {
        @strongify(self)
        return [self.vm sectionCellCount:section tableView:tableView];
    })
    .cellHeight(^CGFloat(NSIndexPath * _Nonnull indexPath, UITableView * _Nonnull tableView) {
        @strongify(self)
        return [self.vm cellHeight:indexPath tableView:tableView];
    })
    .cell(^UITableViewCell * _Nullable(NSIndexPath * _Nonnull indexPath, UITableView * _Nonnull tableView) {
        @strongify(self)
        return [self.vm cell:indexPath tableView:tableView];
    })
    .select(^(NSIndexPath * _Nonnull indexPath, UITableView * _Nonnull tableView) {
        @strongify(self)
        return [self.vm select:indexPath tableView:tableView];
    })
    .willDisplayCell(^(NSIndexPath * _Nonnull indexPath, UITableView * _Nonnull tableView, UITableViewCell * _Nonnull cell) {
        @strongify(self)
        return [self.vm willDisplayCell:indexPath tableView:tableView cell:cell];
    })
    .didScroll(^(UIScrollView * _Nonnull scrollView) {
        @strongify(self)
        if (self.enableTapEmpty) {
            [self cancelKeyboard];
        }
        return [self.vm didScroll:scrollView];
    })
    ;
    [_tableview startRun];
    _tableview.backgroundColor = [UIColor clearColor];
    
    // 刷新配置
    [self refreshTableConfig];
    
    // 固定row
    [self.vm forRows];
    // 获取数据
    [self.vm refreshData:nil];
}

//MARK: - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if([touch.view isKindOfClass:[UITableViewCell class]]) {
         return NO;
    }
    // UITableViewCellContentView => UITableViewCell
    if([touch.view.superview isKindOfClass:[UITableViewCell class]]) {
         return NO;
    }
    // UITableViewCellContentView => UITableViewCellScrollView => UITableViewCell
    if([touch.view.superview.superview isKindOfClass:[UITableViewCell class]]) {
         return NO;
    }
    return YES;
}

- (void)hiddeKeyboard:(UIGestureRecognizer *)recognizer {
    [self.tableview endEditing:true];
    [self cancelKeyboard];
}

//MARK: - lazy
- (UITableView *)tableview {
    if (!_tableview) {
        _tableview = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 0, 0) style:UITableViewStylePlain];
        if (@available(iOS 11.0, *)) {
            _tableview.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        }
        if (@available(iOS 15.0, *)) {
            _tableview.sectionHeaderTopPadding = 0;
        }
    } 
    return _tableview;
}

- (TableVCVM *)vm {
    if (!_vm) {
        _vm = [[self.vmClass alloc] init];
        @weakify(self);
        _vm.block = ^id _Nullable(id  _Nullable obj) {
            @strongify(self);
            if ([@"self" isEqualToString:obj]) {
                return self;
            }
            if ([@"table" isEqualToString:obj]) {
                return self.tableview;
            }
            if ([@"view" isEqualToString:obj]) {
                return self.view;
            }
            if ([@"all" isEqualToString:obj]) {
                return @[self, self.tableview];
            }
            return nil;
        };
    }
    return _vm;
}

- (void)setBlock:(BlockId)block {
    _block = block;
    if (block) {
        [self.vm.transmitSignal subscribeNext:^(id  _Nullable x) {
            block(x);
        }];
    }
}

//MARK: - setter
- (void)setTransmitBlock:(BlockId)transmitBlock {
    _transmitBlock = transmitBlock;
    if (transmitBlock) {
        [self.vm.transmitSignal subscribeNext:^(id  _Nullable x) {
            transmitBlock(x);
        }];
    }
}

// MARK:- class初始化
+ (instancetype)vcWithClassStr:(NSString *)clsStr {
    return [[self alloc] initWithClass:NSClassFromString(clsStr) model:nil];
}

+ (instancetype)vcWithClassStr:(NSString *)clsStr model:(id)model {
    return [[self alloc] initWithClass:NSClassFromString(clsStr) model:model];
}

+ (instancetype)vcWithClass:(Class)cls {
    return [[self alloc] initWithClass:cls model:nil];
}

+ (instancetype)vcWithClass:(Class)cls model:(id)model {
    return [[self alloc] initWithClass:cls model:model];
}

- (instancetype)initWithClass:(Class)cls model:(id)model {
    if (self = [super init]) {
        NSString *className = [NSString stringWithFormat:@"%@_%@", NSStringFromClass(self.class), NSStringFromClass(cls)];
        NSString *key = [NSString stringWithFormat:@"%@_%f_%u", className, NSDate.new.timeIntervalSince1970, arc4random()];
        self.bindKey = key;
        [self addActionObserver];
        self.vmClass = cls;
        self.vm.bindKey = key;
        self.model = model;
        self.vm.model = model;
        self.enableEmptyConifg = true;
        [self.vm initDown];
        //
        if (jBaseSDK.jSignDebugModel) {
            NSLog(@"VM --> %@", NSStringFromClass(cls));
        }
    }
    return self;
}

- (void)addActionObserver {
    NSLog(@"%@", self.bindKey);
    @weakify(self);
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:self.bindKey object:nil] subscribeNext:^(NSNotification * _Nullable x) {
        ActionModel *action = (ActionModel *)x.object;
        @strongify(self);
        if ([action runTarget:self.vm]) {
            return;
        }
        if ([action runTarget:self]) {
            return;
        }
    }];
}

//MARK:- lifecycle
- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        if ([self.vm conformsToProtocol:@protocol(VCLifecycleProtocol)]) {
            if ([self.vm respondsToSelector:@selector(startWithCoder:)]) {
                [self.vm performSelector:@selector(startWithCoder:) withObject:coder];
            }
        }
    }
    return self;
}

- (void)awakeFromNib{
    [super awakeFromNib];
    if ([self.vm conformsToProtocol:@protocol(VCLifecycleProtocol)]) {
        if ([self.vm respondsToSelector:@selector(startFromNib)]) {
            [self.vm performSelector:@selector(startFromNib)];
        }
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self configNavBar];
    if ([self.vm conformsToProtocol:@protocol(VCLifecycleProtocol)]) {
        if ([self.vm respondsToSelector:@selector(didLoad)]) {
            [self.vm performSelector:@selector(didLoad)];
        }
    }
}

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    if ([self.vm conformsToProtocol:@protocol(VCLifecycleProtocol)]) {
        if ([self.vm respondsToSelector:@selector(willAppear:)]) {
            [self.vm performSelector:@selector(willAppear:) withObject:@(animated)];
        }
    }
}

- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    if ([self.vm conformsToProtocol:@protocol(VCLifecycleProtocol)]) {
        if ([self.vm respondsToSelector:@selector(willLayoutSubviews)]) {
            [self.vm performSelector:@selector(willLayoutSubviews)];
        }
    }
}

- (void)viewDidLayoutSubviews{
    [super viewWillLayoutSubviews];
    if ([self.vm conformsToProtocol:@protocol(VCLifecycleProtocol)]) {
        if ([self.vm respondsToSelector:@selector(didLayoutSubviews)]) {
            [self.vm performSelector:@selector(didLayoutSubviews)];
        }
    }
}

- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    if ([self.vm conformsToProtocol:@protocol(VCLifecycleProtocol)]) {
        if ([self.vm respondsToSelector:@selector(didAppear:)]) {
            [self.vm performSelector:@selector(didAppear:) withObject:@(animated)];
        }
    }
}

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    if ([self.vm conformsToProtocol:@protocol(VCLifecycleProtocol)]) {
        if ([self.vm respondsToSelector:@selector(willDisappear:)]) {
            [self.vm performSelector:@selector(willDisappear:) withObject:@(animated)];
        }
    }
}

- (void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    if ([self.vm conformsToProtocol:@protocol(VCLifecycleProtocol)]) {
        if ([self.vm respondsToSelector:@selector(didDisappear:)]) {
            [self.vm performSelector:@selector(didDisappear:) withObject:@(animated)];
        }
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    if ([self.vm conformsToProtocol:@protocol(VCLifecycleProtocol)]) {
        if ([self.vm respondsToSelector:@selector(receiveMemoryWarning)]) {
            [self.vm performSelector:@selector(receiveMemoryWarning)];
        }
    }
}

// MARK:- dealloc
- (void)dealloc {
    NSLog(@"VM --> %@", self.bindKey);
}

// MARK: - lazy
- (TableNavbarV *)navigationV {
    if (!_navigationV) {
        _navigationV = [[TableNavbarV alloc] init];
        [self.view addSubview:_navigationV];
        [_navigationV mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.top.right.equalTo(self.view).offset(0);
            make.height.mas_equalTo(kStatusBar_Height + kNavigationBar_Height);
        }];
    }
    return _navigationV;
}

- (RACSubject *)delayReloadSubject {
    if (!_delayReloadSubject) {
        _delayReloadSubject = [RACSubject subject];
    }
    return _delayReloadSubject;
}



@end
